﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Sinc.ERP.Core.Enum;

namespace Sinc.ERP.Application;

/// <summary>
/// 实体卡基础输入参数
/// </summary>
public class ProductCardBaseInput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    public virtual long? Id { get; set; }

    /// <summary>
    /// 产品Id
    /// </summary>
    [Required(ErrorMessage = "产品Id不能为空")]
    public virtual long? ProductId { get; set; }

    /// <summary>
    /// 导入批次号
    /// </summary>
    [Required(ErrorMessage = "导入批次号不能为空")]
    public virtual string BatchNumber { get; set; }

    /// <summary>
    /// ICCID
    /// </summary>
    [Required(ErrorMessage = "ICCID不能为空")]
    public virtual string Code { get; set; }

    /// <summary>
    /// 校验码
    /// </summary>
    public virtual string? Passcode { get; set; }

    /// <summary>
    /// 成本价
    /// </summary>
    [Required(ErrorMessage = "成本价不能为空")]
    public virtual decimal? CostPrice { get; set; }

    /// <summary>
    /// 有效期
    /// </summary>
    [Required(ErrorMessage = "有效期不能为空")]
    public virtual DateTime ExpirationDate { get; set; }

    /// <summary>
    /// 状态
    /// </summary>
    [Dict("ProductCardStatusEnum", AllowNullValue = true)]
    [Required(ErrorMessage = "状态不能为空")]
    public virtual int? Status { get; set; }

    /// <summary>
    /// 所属客户
    /// </summary>
    [Required(ErrorMessage = "所属客户不能为空")]
    public virtual long? CustomerId { get; set; }

}

/// <summary>
/// 实体卡分页查询输入参数
/// </summary>
public class PageProductCardInput : BasePageInput
{
    /// <summary>
    /// 产品Id
    /// </summary>
    public long? ProductId { get; set; }

    /// <summary>
    /// 导入批次号
    /// </summary>
    public string BatchNumber { get; set; }

    /// <summary>
    /// ICCID
    /// </summary>
    public string Code { get; set; }

    /// <summary>
    /// 校验码
    /// </summary>
    public string? Passcode { get; set; }

    /// <summary>
    /// 成本价
    /// </summary>
    public decimal? CostPrice { get; set; }

    /// <summary>
    /// 有效期范围
    /// </summary>
    public DateTime? ExpirationDate { get; set; }

    /// <summary>
    /// 状态
    /// </summary>
    [Dict("ProductCardStatusEnum", AllowNullValue = true)]
    public ProductCardStatusEnum? Status { get; set; }

    /// <summary>
    /// 所属客户
    /// </summary>
    public long? CustomerId { get; set; }

    /// <summary>
    /// 选中主键列表
    /// </summary>
    public List<long> SelectKeyList { get; set; }

    /// <summary>
    /// 是否返回校验码 
    /// </summary>
    public bool IncludePasscode { get; set; }
}

/// <summary>
/// 实体卡增加输入参数
/// </summary>
public class AddProductCardInput
{
    /// <summary>
    /// 产品Id
    /// </summary>
    [Required(ErrorMessage = "产品Id不能为空")]
    public long? ProductId { get; set; }

    /// <summary>
    /// 成本价
    /// </summary>
    [Required(ErrorMessage = "成本价不能为空")]
    public decimal? CostPrice { get; set; }

    /// <summary>
    /// 有效期
    /// </summary>
    [Required(ErrorMessage = "有效期不能为空")]
    public DateTime ExpirationDate { get; set; }

    [Required(ErrorMessage = "号码段不能为空")]
    public string CodeRange { get; set; }

    public IList<string> GetNumberList()
    {
        var numberList = new List<string>();
        if (string.IsNullOrWhiteSpace(this.CodeRange))
            return numberList;

        var numberSegmentList = this.CodeRange.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
        foreach (var numberSegment in numberSegmentList)
        {
            var partsList = numberSegment.Split(["\t", " "], 2, StringSplitOptions.RemoveEmptyEntries);
            numberList.Add(partsList[0].SubstringProductCode());
            if (partsList.Length == 1)
                continue;

            if (partsList[0].Length != partsList[1].Length)
                throw new ArgumentException($"{numberSegment} 起始号码段不是同类型");
            if (!decimal.TryParse(partsList[0].SubstringProductCode(), out var startNumber))
                throw new ArgumentException($"{numberSegment} 不是有效的号码段格式");
            if (!decimal.TryParse(partsList[1].SubstringProductCode(), out var endNumber))
                throw new ArgumentException($"{numberSegment} 不是有效的号码段格式");

            while (startNumber < endNumber)
            {
                startNumber++;
                numberList.Add(startNumber.ToString());
            }
        }
        return numberList;
    }

    public List<ProductCard> Convert()
    {
        var modelList = new List<ProductCard>();
        var numberList = this.GetNumberList();
        foreach (var number in numberList)
        {
            var model = this.Adapt<ProductCard>();
            model.Id = YitIdHelper.NextId();
            model.Code = number;
            model.FullCode = number;
            model.Status = ProductCardStatusEnum.Created;
            model.OrgId = Sinc.ERP.Core.SeedData.SysOrgSeedData.DefaultOrgId;
            model.CustomerId = Sinc.ERP.Core.SeedData.SysOrgSeedData.DefaultOrgId;
            model.CreateTime = DateTime.Now;
            modelList.Add(model);
        }
        return modelList;
    }
}

/// <summary>
/// 实体卡删除输入参数
/// </summary>
public class DeleteProductCardInput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    [Required(ErrorMessage = "主键Id不能为空")]
    public long? Id { get; set; }
}

/// <summary>
/// 实体卡更新输入参数
/// </summary>
public class UpdateProductCardInput
{
    /// <summary>
    /// 主键Id
    /// </summary>    
    [Required(ErrorMessage = "主键Id不能为空")]
    public long? Id { get; set; }

    /// <summary>
    /// 产品Id
    /// </summary>    
    [Required(ErrorMessage = "产品Id不能为空")]
    public long? ProductId { get; set; }

    /// <summary>
    /// 导入批次号
    /// </summary>    
    [Required(ErrorMessage = "导入批次号不能为空")]
    [MaxLength(50, ErrorMessage = "导入批次号字符长度不能超过50")]
    public string BatchNumber { get; set; }

    /// <summary>
    /// ICCID
    /// </summary>    
    [Required(ErrorMessage = "ICCID不能为空")]
    [MaxLength(100, ErrorMessage = "ICCID字符长度不能超过100")]
    public string Code { get; set; }

    /// <summary>
    /// 校验码
    /// </summary>    
    [MaxLength(50, ErrorMessage = "校验码字符长度不能超过50")]
    public string? Passcode { get; set; }

    /// <summary>
    /// 成本价
    /// </summary>    
    [Required(ErrorMessage = "成本价不能为空")]
    public decimal? CostPrice { get; set; }

    /// <summary>
    /// 有效期
    /// </summary>    
    [Required(ErrorMessage = "有效期不能为空")]
    public DateTime ExpirationDate { get; set; }

    /// <summary>
    /// 状态
    /// </summary>    
    [Dict("ProductCardStatusEnum", AllowNullValue = true)]
    [Required(ErrorMessage = "状态不能为空")]
    public int? Status { get; set; }

    /// <summary>
    /// 所属客户
    /// </summary>    
    [Required(ErrorMessage = "所属客户不能为空")]
    public long? CustomerId { get; set; }

}

/// <summary>
/// 实体卡主键查询输入参数
/// </summary>
public class QueryByIdProductCardInput : DeleteProductCardInput
{

}

/// <summary>
/// 实体卡数据导入实体
/// </summary>
[ExcelImporter(SheetIndex = 1, IsOnlyErrorRows = true)]
public class ImportProductCardInput : BaseImportInput
{
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(IsIgnore = true)]
    public long? ProductId { get; set; }

    /// <summary>
    /// 产品名称
    /// </summary>
    [ImporterHeader(Name = "*产品名称")]
    [ExporterHeader("*产品名称", Format = "", Width = 25, IsBold = true)]
    public string? ProductName { get; set; }

    /// <summary>
    /// 导入批次号
    /// </summary>
    [ImporterHeader(Name = "*导入批次号")]
    [ExporterHeader("*导入批次号", Format = "", Width = 25, IsBold = true)]
    public string BatchNumber { get; set; }

    /// <summary>
    /// ICCID
    /// </summary>
    [ImporterHeader(Name = "*ICCID")]
    [ExporterHeader("*ICCID", Format = "", Width = 25, IsBold = true)]
    public string Code { get; set; }

    /// <summary>
    /// 成本价
    /// </summary>
    [ImporterHeader(Name = "*成本价")]
    [ExporterHeader("*成本价", Format = "", Width = 15, IsBold = true)]
    public decimal? CostPrice { get; set; }

    /// <summary>
    /// 有效期
    /// </summary>
    [ImporterHeader(Name = "*有效期")]
    [ExporterHeader("*有效期", Format = "yyyy-MM-dd", Width = 15, IsBold = true)]
    public DateTime ExpirationDate { get; set; }

    /// <summary>
    /// 状态 关联值
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(IsIgnore = true)]
    public ProductCardStatusEnum? Status { get; set; }

    /// <summary>
    /// 状态 文本
    /// </summary>
    [Dict("ProductCardStatusEnum")]
    [ImporterHeader(Name = "*状态")]
    [ExporterHeader("*状态", Format = "", Width = 15, IsBold = true)]
    public string StatusLabel { get; set; }
}

public class FillInProductCardInput
{
    /// <summary>
    /// 提交内容
    /// </summary>
    public string Barcode { get; set; }

    /// <summary>
    /// 是否是批量提交
    /// </summary>
    public bool IsBatch { get; set; }

    #region 转换解析结果
    /// <summary>
    /// 转换解析结果
    /// </summary>
    /// <returns></returns>
    public Dictionary<string, string> Convert()
    {
        var result = new Dictionary<string, string>();
        if (this.Barcode.IsEmpty())
            return result;

        // https://rnr.hk.chinamobile.com/realname/#/real/index?iccid=89852122405073411805&passcode=XMMOED
        var lineList = this.Barcode.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
        foreach (var line in lineList)
        {
            if (line.IsEmpty())
                continue;

            if (line.StartsWith("http"))
            {
                var partsList = line.Split(new[] { "?", "&" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                var codePartsList = partsList.FirstOrDefault(x => x.StartsWith("iccid="))?.Split(new[] { "=" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (codePartsList.Count != 2)
                    continue;
                var passcodePartsList = partsList.FirstOrDefault(x => x.StartsWith("passcode="))?.Split(new[] { "=" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (passcodePartsList.Count != 2)
                    continue;

                if (codePartsList[1].IsEmpty() || passcodePartsList[1].IsEmpty())
                    continue;
                result[codePartsList[1]] = passcodePartsList[1];
            }
            else
            {
                var partsList = line.Split(new[] { "\t", " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (partsList.Count != 2)
                    continue;

                result[partsList[0]] = partsList[1];
            }
        }

        return result;
    }
    #endregion
}

/// <summary>
/// 调拨实体卡
/// </summary>
public class TransferProductCardInput
{
    /// <summary>
    /// 产品Id
    /// </summary>
    [Required(ErrorMessage = "产品Id不能为空")]
    public long? ProductId { get; set; }

    [Required(ErrorMessage = "目标客户不能为空")]
    public long? ToCustomerId { get; set; }

    /// <summary>
    /// 调拨数量
    /// </summary>
    public int Qty { get; set; }

    public string CodeRange { get; set; }

    public IList<string> GetNumberList()
    {
        var numberList = new List<string>();
        if (string.IsNullOrWhiteSpace(this.CodeRange))
            return numberList;

        var numberSegmentList = this.CodeRange.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
        foreach (var numberSegment in numberSegmentList)
        {
            var partsList = numberSegment.Split(["\t", " "], 2, StringSplitOptions.RemoveEmptyEntries);
            numberList.Add(partsList[0].SubstringProductCode());
            if (partsList.Length == 1)
                continue;

            if (partsList[0].Length != partsList[1].Length)
                throw new ArgumentException($"{numberSegment} 起始号码段不是同类型");
            if (!decimal.TryParse(partsList[0].SubstringProductCode(), out var startNumber))
                throw new ArgumentException($"{numberSegment} 不是有效的号码段格式");
            if (!decimal.TryParse(partsList[1].SubstringProductCode(), out var endNumber))
                throw new ArgumentException($"{numberSegment} 不是有效的号码段格式");

            while (startNumber < endNumber)
            {
                startNumber++;
                numberList.Add(startNumber.ToString());
            }
        }
        return numberList;
    }
}

public class SetStatusProductCardInput
{
    /// <summary>
    /// 主键Id
    /// </summary>
    [Required(ErrorMessage = "主键Id不能为空")]
    public long[] IdList { get; set; }

    /// <summary>
    /// 状态
    /// </summary>
    [Dict("ProductCardStatusEnum")]
    [Required(ErrorMessage = "状态不能为空")]
    public ProductCardStatusEnum Status { get; set; }
}